/**
 * 
 */
package com.detroitchow2;



import java.util.ArrayList;

import com.detroitchow2.layout.EmptyWindow;
import com.detroitchow2.util.LogUtil;
import com.detroitchow2.vo.StoreVO;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.GoogleMap.OnCameraChangeListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import android.app.ActionBar;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.BitmapDrawable;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.FragmentActivity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;

/**
 * @author dave
 *
 */
public class MapScreen extends FragmentActivity
implements OnMarkerClickListener, OnCameraChangeListener, OnTouchListener, OnClickListener, OnMapClickListener, LocationListener
{
  private GoogleMap gMap;
  private StoreService storeService;
  private ArrayList<StoreVO> stores=null;
  private PopupWindow pw;
  private Marker currentMarker;
  private boolean suppressPopup = true;
  private String selectedMapInent;
  private Intent myIntent;
  private Context myContext;
  private final int TRAFFIC_LAYER=23232;
  private final int SATELLITE_LAYER=23245;
  private final int TERRAIN_LAYER=23246;
  private final int NORMAL_LAYER=23247;
  private final int HYBRID_LAYER=23248;
  private final int DEFAULT_GOOGLE_MAP_TYPE = GoogleMap.MAP_TYPE_NORMAL;
  private ProgressDialog pd;
  private LocationManager locationManager;
  private int locationDurationCheck=0;
  private boolean isLocationCheckComplete=false;
  protected Handler taskHandler = new Handler();
  private int DEFAULT_ZOOM = 15;
  
  
  @Override
  protected void onCreate(Bundle savedInstanceState) 
  {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.map);
      setUpMapIfNeeded();
      LogUtil.log("ONCreate", "executed");
      myContext = this;
  }
  
  @Override
  public boolean onCreateOptionsMenu(Menu menu)
  {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    ActionBar actionBar = getActionBar(); // || getActionBar();
    actionBar.setIcon(getResources().getDrawable(R.drawable.action_bar_icon));
    actionBar.setDisplayHomeAsUpEnabled(true);
    actionBar.setTitle("");
    menu.add(0, TRAFFIC_LAYER, menu.size(), "Traffic"); 
    menu.add(0, SATELLITE_LAYER, menu.size(), "Satellite"); 
    menu.add(0, TERRAIN_LAYER, menu.size(), "Terrain"); 
    menu.add(0, HYBRID_LAYER, menu.size(), "Hybrid");
    menu.add(0, NORMAL_LAYER, menu.size(), "Normal"); 
    
    return true;
    
  }
  
  @Override
  public boolean onOptionsItemSelected(MenuItem item) 
  {
    Intent intent;
    int type;
    switch (item.getItemId()) {
    
      case HYBRID_LAYER:
        type = GoogleMap.MAP_TYPE_HYBRID;
        if(gMap.getMapType() == GoogleMap.MAP_TYPE_HYBRID)
          type = DEFAULT_GOOGLE_MAP_TYPE;
         gMap.setMapType(type);
        return false;
    
        case SATELLITE_LAYER:
          type = GoogleMap.MAP_TYPE_SATELLITE;
          if(gMap.getMapType() == GoogleMap.MAP_TYPE_SATELLITE)
            type = DEFAULT_GOOGLE_MAP_TYPE;
           gMap.setMapType(type);
          return false;
          
        case TERRAIN_LAYER:
          type = GoogleMap.MAP_TYPE_TERRAIN;
          if(gMap.getMapType() == GoogleMap.MAP_TYPE_TERRAIN)
            type = DEFAULT_GOOGLE_MAP_TYPE;
           gMap.setMapType(type);
          return false;
          
        case NORMAL_LAYER:
          gMap.setMapType(DEFAULT_GOOGLE_MAP_TYPE);
          return false;
      
        case TRAFFIC_LAYER:
          gMap.setTrafficEnabled(!gMap.isTrafficEnabled());
          return false;
        case android.R.id.home:
          intent = new Intent(this, MainActivity.class);
          startActivityForResult(intent, 0);
          return false;
      
        case R.id.refresh:
          intent = new Intent(this, MainActivity.class);
          intent.putExtra(AppIntent.REFRESH, true);
          startActivityForResult(intent, 0);
          return false;
          
        case R.id.search:
          
          intent = new Intent(this, SearchActivity.class);
          startActivityForResult(intent, 0);
          
        case R.id.location:
          handleLocationRequest() ;
         // intent = new Intent(this, SearchActivity.class);
         // startActivityForResult(intent, 0);
          
        default:
            return super.onOptionsItemSelected(item);
    }
  }
  
  @Override
  protected void onResume() 
  {
      super.onResume();
      setUpMapIfNeeded();
      
      LogUtil.log("onResume", "executed");
      
      int selectedStoreId = -1;
      int overrideStoreId = -1;
      try
      {
        Bundle bundle = getIntent().getExtras();
        selectedMapInent= bundle.getString(AppIntent.MAP_INTENT);
        selectedStoreId = bundle.getInt(StoreService.SELECTED_STORE_KEY);
        overrideStoreId = bundle.getInt(StoreService.SELECTED_STORE_OVERRIDE);
      }catch(Exception e)
      {
        selectedMapInent =  AppIntent.ISSUE_DETECTED;
      }
      
      LogUtil.log("MapScreen.OnResume", "Intent: " + selectedMapInent);
      
      if(selectedMapInent.equals(AppIntent.ISSUE_DETECTED))
        handleBadIntent();
       else if(selectedMapInent.equals(AppIntent.SELECT_STORE))
       {
         StoreVO svo = storeService.getStore(selectedStoreId);
         Runnable myRun = new StoreLoaderRunnable(svo);
         findViewById(R.id.map).post(myRun);
         suppressPopup = true;
         gMap.moveCamera
         (
             CameraUpdateFactory.newLatLngZoom
               (new LatLng(Double.parseDouble(svo.lat), Double.parseDouble(svo.lng)), DEFAULT_ZOOM)
         );
         
       }
       // handleSelectStore(selectedStoreId, overrideStoreId);
      else if(selectedMapInent.equals(AppIntent.LOCATION))
        handleLocationRequest() ;
      
      
      
  }
  
private void handleLocationRequest()
  {
  pd = ProgressDialog.show(this, "Working..","Searching for location", true,false);
  setTimer(3000);
  if(locationManager == null) 
  {
    locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
    
  }
  
  Criteria criteria = new Criteria();
   criteria.setAccuracy(Criteria.ACCURACY_FINE);
   criteria.setAltitudeRequired(false);
   criteria.setBearingRequired(false);
   criteria.setCostAllowed(true);
   String strLocationProvider = locationManager.getBestProvider(criteria, true);
   Location lastKnownLocation = locationManager.getLastKnownLocation(strLocationProvider);
  
  if(lastKnownLocation != null){
    if(pd != null)
       pd.dismiss();
    onLocationChanged(lastKnownLocation);
  }
  
  locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L, 1000.0f, this);
    
  }

//go home
 private void handleBadIntent() 
 {
    myIntent = new Intent(this, MainActivity.class);
    startActivityForResult(myIntent, 0);
 }
  
  private void setUpMapIfNeeded() 
  {
    // Do a null check to confirm that we have not already instantiated the map.
    if (gMap == null) {
        // Try to obtain the map from the SupportMapFragment.
      gMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
        // Check if we were successful in obtaining the map.
        if (gMap != null) {
            setUpMap();
        }
      
     
    }
  }
  
  private void setUpMap() 
  {
    // Hide the zoom controls as the button panel will cover it.
    gMap.getUiSettings().setZoomControlsEnabled(false);

    gMap.setMyLocationEnabled(true);
    gMap.setIndoorEnabled(true);
    gMap.setOnMapClickListener(this);
    gMap.setMapType(DEFAULT_GOOGLE_MAP_TYPE);
    
    // Add lots of markers to the map.
    addMarkersToMap();

    // Setting an info window adapter allows us to change the both the contents and look of the
    // info window.
    InfoWindowAdapter window = new EmptyWindow(this);
    gMap.setInfoWindowAdapter(window);
   
    
    //gMap.setInfoWindowAdapter(null);
    // Set listeners for marker events.  See the bottom of this class for their behavior.
    gMap.setOnMarkerClickListener(this);
    gMap.setOnCameraChangeListener(this);
    //gMap.setOnInfoWindowClickListener(this);
    
    // Pan to see all markers in view.
    // Cannot zoom to bounds until the map has a size.
    final View mapView = getSupportFragmentManager().findFragmentById(R.id.map).getView();
    
    
  }



  private void addMarkersToMap()
  {
    try
    {
      storeService = ((StoreService)getApplicationContext());
    }catch(Exception e)
    {
      LogUtil.log("mapScreen", "In Exception..............");
      LogUtil.log("mapScreen when storeService are null", e.getMessage());
    }
    
    if(stores == null){
      try
      {
        stores = storeService.getStoresListForMap();
        LogUtil.log("MapScreenonCreate", "stores: " + stores.size());
        
        for(StoreVO s : stores)
        {
          LogUtil.log("mapScreen", "Add marker: lat: " + s.lat + " lng: " + s.lng  );
          gMap.addMarker
            (
              new MarkerOptions()
              .position(getLatLong(s))
              .title(String.valueOf(s.storeId))
              .snippet(null)
              .icon(BitmapDescriptorFactory.fromResource(R.drawable.marker))
            );
        }
      }catch(Exception e)
      {
        Intent intent = new Intent(this, MainActivity.class);
        startActivityForResult(intent, 0);
        LogUtil.log("mapScreen when stores == null", e.getMessage());
        e.printStackTrace();
      }
    }else
      LogUtil.log("stores is null", "stores is null");
    
  }

  private LatLng getLatLong(StoreVO s)
  {
    double lat=0d;
    double lng=0d;
    try
    {
      lat =Double.parseDouble(s.lat);
      lng =Double.parseDouble(s.lng);
    }catch(Exception e)
    {
      
    }
    return new LatLng(lat, lng);
  }

  @Override
  public boolean onMarkerClick(Marker marker)
  {
    LogUtil.log("onMarkerClick", "clicked");
    suppressPopup = false;
    currentMarker = marker;
    currentMarker.hideInfoWindow();
    return false;
  }
  
  private OnClickListener onCloseWindowListener = new OnClickListener() 
  {
    public void onClick(View v) 
    {
        LogUtil.log("onCloseWindowListener", "isOutside: " + pw.isOutsideTouchable());
        pw.dismiss();
        suppressPopup = true;
    }
  };
  
  private OnClickListener onNavButtonClickListener = 
      new OnClickListener() 
  {
    public void onClick(View v) 
    {
        LogUtil.log("onNavButtonClickListener", "Hey");
        pw.dismiss();
        StoreVO s = (StoreVO) v.getTag();
        if(s.address != null) 
        {
          String addressLine = s.address;
          if(s.city != null)
            addressLine += "+" + s.city;
          
          if(s.state != null)
            addressLine += "+" + s.state;
          
          if(s.zip != null)
            addressLine += "+" + s.zip;
          
          addressLine = addressLine.replaceAll(" ", "+");
          LogUtil.log("navButtonClickListener", addressLine);
         Intent intent = new Intent(android.content.Intent.ACTION_VIEW,
          Uri.parse("http://maps.google.com/maps?daddr=" + addressLine));
          myContext.startActivity(intent);
        }
    }
 
  };
  
  private OnClickListener onArticlesClickListener = 
      new OnClickListener() 
  {
    public void onClick(View v) 
    {
        StoreVO s = (StoreVO) v.getTag();
        LogUtil.log("onArticlesClickListener", "Hey" + s.name);
        pw.dismiss();
        
        if(s != null)
        {
          Intent intent = new Intent(myContext, ArticleActivity.class);
          intent.putExtra(StoreService.SELECTED_STORE_KEY, s.storeId);
          startActivityForResult(intent, 0);
        }
        
    }
  };
  
  //Create an anonymous implementation of OnClickListener
  private OnClickListener onPhoneClickListener = new OnClickListener() {
      public void onClick(View v) 
      {
        StoreVO s = (StoreVO) v.getTag();
        if(s != null)
        {
          String phone = s.getPhoneIntentFormat();
          LogUtil.log("BalloonOverlayView", "onClick Phone: " + phone);
          Intent intent = new Intent(Intent.ACTION_DIAL);
          intent.setData(Uri.parse(phone));
          myContext.startActivity(intent);
        }
        
      }
  };
  
  //Create an anonymous implementation of OnClickListener
  private OnClickListener onWebClickListener = new OnClickListener() {
      public void onClick(View v) 
      {
        StoreVO s = (StoreVO) v.getTag();
        if(s != null && s.website != null && s.website.length() > 0)
        {
          String url = s.website;
          Intent intent = new Intent(Intent.ACTION_VIEW);
          intent.setData(Uri.parse(url));
          myContext.startActivity(intent);
        } else
        {
          int duration = Toast.LENGTH_SHORT;
          Toast toast = Toast.makeText(myContext, "Web Site not available", duration);
          toast.show();
        }
      }
  };
  private boolean onLocationChanged;  
  
  
  @Override
  public void onCameraChange(CameraPosition arg0)
  {
    LogUtil.log("onCameraChange", "enter method");
    
    if(onLocationChanged)
    {
      gMap.animateCamera(CameraUpdateFactory.zoomTo(DEFAULT_ZOOM));
      onLocationChanged = false;
      suppressPopup = true;
      
    } else if (!suppressPopup && gMap !=  null && currentMarker != null)
    {
      
      currentMarker.hideInfoWindow();
      LogUtil.log("onCameraChange", currentMarker.getTitle());
      int selectedStoreId = Integer.parseInt(currentMarker.getTitle());
      popupWindow
        (
          storeService.getStore(selectedStoreId)
        );
      suppressPopup = true;
    }
    
    
  }
  
  private void popupWindow(StoreVO s)
  {
    LayoutInflater inflater = 
        (LayoutInflater) MapScreen.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    //Inflate the view from a predefined XML layout
    View layout = inflater.inflate(R.layout.custom_info_window,
        (ViewGroup) findViewById(R.id.infowindow));
    
    ImageView btnClose = (ImageView) layout.findViewById(R.id.close_img_button);
    btnClose.setOnClickListener(onCloseWindowListener);
    
    Button btnNav = (Button)layout.findViewById(R.id.btnNav);
    btnNav.setTag(s);
    btnNav.setOnClickListener(onNavButtonClickListener);
    
    Button btnArticles = (Button)layout.findViewById(R.id.btnComment);
    btnArticles.setTag(s);
    btnArticles.setOnClickListener(onArticlesClickListener);
    
    Button btnPhone = (Button)layout.findViewById(R.id.btnPhone);
    btnPhone.setTag(s);
    btnPhone.setOnClickListener(onPhoneClickListener);
    
    Button btnWeb = (Button)layout.findViewById(R.id.btnWeb);
    btnWeb.setTag(s);
    btnWeb.setOnClickListener(onWebClickListener);
    
    
    TextView txtTitle = (TextView)layout.findViewById(R.id.balloon_item_title);
    txtTitle.setText(s.name);
    TextView txtSnippet = (TextView)layout.findViewById(R.id.balloon_item_snippet);
    txtSnippet.setText(s.getSnippetLayout());
    
    layout.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
    int popupHeight = layout.getMeasuredHeight();
    int yCord = (int)(popupHeight * .33) * -1;
    
    if(s.isListItem == 0)
    {
      popupHeight += 85;
      yCord -= 50;
    }
      
    
    LogUtil.log("Calc", "popupHeight: " + popupHeight + "  CalcedY:" + yCord);
    //pw = new PopupWindow(layout, 400, popupHeight, true);
    pw = new PopupWindow(layout, layout.getMeasuredWidth(), popupHeight, true);
    pw.setOutsideTouchable(true);
    pw.setFocusable(true);
    pw.setTouchable(true);
    pw.setBackgroundDrawable(new BitmapDrawable());
    
    // display the popup in the center
    pw.showAtLocation(layout, Gravity.CENTER, 0, yCord);
    
    
    //layout.setOnClickListener(this);
  }

  @Override
  public boolean onTouch(View v, MotionEvent event)
  {
    LogUtil.log("onTouch", "");
    
    if( pw != null) 
      pw.dismiss();
    return false;
  }

  @Override
  public void onClick(View v)
  {
    LogUtil.log("onClick", "");
    
    if( pw != null) 
    {
      pw.dismiss();
    }
      
    
  }

  @Override
  public void onMapClick(LatLng point)
  {
    LogUtil.log("onMapClick", "");
    
  }
  
  public class StoreLoaderRunnable implements Runnable 
  {
    private StoreVO s;
    public StoreLoaderRunnable(StoreVO parameter) 
    {
       this.s = parameter;
    }

    public void run() 
    {
      popupWindow(this.s); 
    }
  }

  @Override
  public void onLocationChanged(Location location)
  {
    LogUtil.log("onLocationChanged","enter method");
    if(pd != null)
      pd.dismiss();
    
    if (location != null) 
    {
      LogUtil.log("onLocationChanged","location != null details lat: " +  location.getLatitude() + " long: " + location.getLongitude());
      //LatLng ltln = new LatLng( (double) (location.getLatitude() * 1E6), (double)( location.getLongitude() * 1E6));
      
      LatLng ltln = new LatLng( location.getLatitude(), location.getLongitude());
     
      onLocationChanged = true;
      gMap.animateCamera(CameraUpdateFactory.newLatLng(ltln));
      //gMap.animateCamera(CameraUpdateFactory.zoomTo(DEFAULT_ZOOM));
     // this.gMap.getProjection().toScreenLocation(ltln);
    //  int _lat =);
    //  int _lng = ;
    //  this.
    //  geoPoint = new GeoPoint(_lat,_lng);
    //  mapController.animateTo(geoPoint);
    //  removeCurrentLocationIcon();
    //  handleIcon(geoPoint);
    }else
      LogUtil.log("onLocationChanged","location is  null");
    
  }

  @Override
  public void onProviderDisabled(String provider)
  {
    // TODO Auto-generated method stub
    
  }

  @Override
  public void onProviderEnabled(String provider)
  {
    // TODO Auto-generated method stub
    
  }

  @Override
  public void onStatusChanged(String provider, int status, Bundle extras)
  {
    // TODO Auto-generated method stub
    
  }
  
  protected void setTimer( long time )
  {
    locationDurationCheck = 0;
    final long elapse = 1000;
    Runnable t = new Runnable() {
      public void run()
      {
        runNextTask();
        
        if( !isLocationCheckComplete )
        {
          taskHandler.postDelayed( this, elapse );
        }else {
          taskHandler.removeCallbacks(this);
        }
      }
    };
    taskHandler.postAtTime( t, time );
  }
  protected void runNextTask()
  {
    // increment number
    locationDurationCheck++;
    if(locationDurationCheck > 10){
      isLocationCheckComplete = true;
      if(pd != null)
        pd.dismiss();
    }
  }
  
  @Override
  protected void onStop() {
    // TODO Auto-generated method stub
    super.onStop();
    LogUtil.log("MapScreen", "onStop");
    // Doing users of app  favor and unregister the LocationManager 
    if(locationManager != null) {
      locationManager.removeUpdates(this);
      locationManager = null;
    }
  }

}


  